﻿using System;
using System.Collections.Generic;
using SGLib.Net;
using System.IO;
using System.Net;
using PBMessage;


class GameCodec : ICodec
{
    public static GameCodec Codec
    {
        get
        {
            if (mCodec == null)
            {
                mCodec = new GameCodec();
            }
            return mCodec;
        }
    }
    static GameCodec mCodec;

    public byte[] Code(params object[] datas)
    {
        int id = (int)datas[0];

        MemoryStream outStream = new MemoryStream();
        MemoryStream ms = new MemoryStream();
        ProtoBuf.Serializer.Serialize(ms, datas[1]);
        int smallsize = IPAddress.HostToNetworkOrder((int)ms.Length + 2);
        byte[] sizeByte = System.BitConverter.GetBytes((UInt32)smallsize);
        outStream.Write(sizeByte, 0, 4);
        short smallMsgId = (System.Int16)System.Net.IPAddress.HostToNetworkOrder((short)id);
        byte[] MsgIdBytes = System.BitConverter.GetBytes(smallMsgId);
        outStream.Write(MsgIdBytes, 0, 2);

        ms.WriteTo(outStream);
        byte[] byteArray = outStream.ToArray();
        return byteArray;
    }
    public object Decode(params object[] datas)
    {
        byte[] byteData = (byte[])datas[0];
        int offset = (int)datas[1];
        int length = (int)datas[2];
        int bodySize = IPAddress.HostToNetworkOrder(System.BitConverter.ToInt32(byteData, offset));
        int msgId = IPAddress.HostToNetworkOrder(System.BitConverter.ToInt16(byteData, offset + 4));

        MemoryStream ms = new MemoryStream(byteData, offset + 6, bodySize - 2);
        var scLogin = ProtoBuf.Meta.RuntimeTypeModel.Default.Deserialize(ms, null, getTypeByMessageId(msgId));
        return new PBPackage() { MessageID = msgId, Data = scLogin };
    }

    public int GetPackageSize(params object[] datas)
    {
        int retSize = IPAddress.HostToNetworkOrder(System.BitConverter.ToInt32((byte[])datas[0],(int)datas[1]));
        return retSize+4;
    }

    System.Type getTypeByMessageId(int msgID)
    {  
        return IDToPBType.TypeDic[msgID];
    }
}

public struct PBPackage : IPackage
{
    public int MessageID;
    public object Data;
}
